標籤:應用程式架構
微服務指南
微服務架構模式是一種將單一應用程式開發為一組小型服務的方式,每個服務都在自己的程序中執行,並透過輕量級機制(通常是 HTTP 資源 API)進行通訊。這些服務是圍繞業務功能建置的,並且可以透過全自動部署機制獨立部署。這些服務的集中管理非常少,它們可以用不同的程式語言撰寫,並使用不同的資料儲存技術。儘管它們的優點讓它們在過去幾年非常流行,但它們也伴隨著增加的分配、減弱的一致性,並且需要在營運管理方面成熟。
微服務
「微服務架構」一詞在過去幾年中興起,用來描述一種特定的軟體應用程式設計方式,即獨立部署服務的套件。儘管沒有對這種架構風格的精確定義,但有一些共同特徵圍繞著業務功能組織、自動化部署、端點中的智慧,以及語言和資料的分散控制。
微前端
良好的前端開發很困難。擴展前端開發,讓許多團隊可以同時處理大型且複雜的產品,更難。在本文中,我們將描述最近將前端巨石分解成許多更小、更易於管理的部分的趨勢,以及這種架構如何提高處理前端程式碼的團隊的效率和效能。除了討論各種優點和成本之外,我們還將介紹一些可用的實作選項,並深入探討一個展示此技術的完整範例應用程式。
使用既有 UI 模式模組化 React 應用程式
既有 UI 模式在前端開發領域中經常未被充分利用,儘管它們在解決 UI 設計中的複雜問題方面已證實其有效性。本文探討將既有 UI 建構模式應用於 React 世界,並提供重構歷程的程式碼範例以展示其優點。重點在於分層架構如何協助組織 React 應用程式,以提升回應能力和因應未來的變更。
分散式系統模式目錄
分散式系統對程式設計構成特定挑戰。它們通常要求我們擁有資料的複本,且這些複本需要保持同步。然而,我們無法依賴處理節點穩定運作,而網路延遲很容易導致不一致。儘管如此,許多組織依賴於一系列核心分散式軟體來處理資料儲存、訊息傳遞、系統管理和運算能力。這些系統會面臨常見問題,並以類似的解決方案加以解決。2020 年,Unmesh Joshi 開始將這些解決方案收集為模式,並在開發過程中將它們發布到這個網站上。2023 年,這些內容以《分散式系統模式》一書出版。此頁面連結到每個模式的簡要摘要,並提供 oreilly.com 上線上電子書出版品的相關章節深度連結。
無伺服器架構
無伺服器架構是應用程式設計,它結合了第三方「後端即服務」(BaaS) 服務,和/或包含在「功能即服務」(FaaS) 平台上以受管理的短暫容器執行的自訂程式碼。透過使用這些構想,以及單頁應用程式等相關構想,此類架構消除了對傳統的持續運作伺服器元件的許多需求。無伺服器架構可能受益於大幅降低的營運成本、複雜性和工程開發時間,但代價是更依賴於供應商依賴關係和相對不成熟的支援服務。
功能切換(又稱功能旗標)
功能切換(通常也稱為功能標記)是一種強大的技術,可讓團隊在不變更程式碼的情況下修改系統行為。它們屬於各種使用類別,在實作和管理切換時,考慮這些分類非常重要。切換會帶來複雜性。我們可以使用智慧切換實作慣例和適當的工具來管理我們的切換組態,以控制這種複雜性,但我們也應該試著限制系統中的切換數量。
面向領域的可觀察性
在我們的軟體系統中,可觀察性一直很有價值,在雲端和微服務的時代變得更加重要。然而,我們新增到系統中的可觀察性往往相當低階且技術性,而且似乎太常需要在我們的程式碼庫中散佈到各種記錄、儀器和分析架構的粗糙且冗長的呼叫。本文描述了一種模式,可清理此混亂,並允許我們以乾淨且可測試的方式新增與業務相關的可觀察性。
敏捷和架構的 Podcast
Ryan Lockard(敏捷起義)邀請我加入 Rebecca Wirfs-Brock,在敏捷專案中討論架構的 Podcast 對話。Rebecca 發展了責任驅動設計,在我開始我的職業生涯時對我影響很大。我們討論了我們如何定義架構、測試對架構的影響、領域模型的角色、要準備什麼類型的文件,以及需要多少架構才能事先完成。
演化式資料庫設計
在過去十年中,我們開發並改進了許多技術,讓資料庫設計可以在應用程式開發時演化。這對敏捷方法而言是非常重要的功能。這些技術依賴於將持續整合和自動化重構套用於資料庫開發,以及 DBA 和應用程式開發人員之間的密切合作。這些技術適用於生產前和已發佈的系統,適用於全新專案和舊有系統。
重構模組相依性
隨著程式規模的擴增,將其拆分成模組非常重要,如此一來,您無須了解所有內容即可進行小幅修改。通常,這些模組可以由不同的團隊提供,並動態地加以結合。在此重構文章中,我使用簡報-網域-資料分層法拆分一個小型程式。然後,我重構這些模組之間的相依性,以引入服務定位器和相依性注入模式。這些模式適用於不同的語言,但看起來卻不同,因此我同時在 Java 和無類別 JavaScript 樣式中顯示這些重構。
重構存取外部服務的程式碼
當我撰寫處理外部服務的程式碼時,我發現將存取程式碼分隔成個別物件非常有價值。在此,我將展示如何將一些凝結的程式碼重構成此分隔的常見模式。
六角形架構與 Rails
我和同事 Badri 關於六角形架構及其在 Rails 應用程式中的角色的對話影片。在第一部影片中,我們討論六角形架構的意義,以及這如何引導我們在持久性架構中選擇 Active Record 和資料對應器模式。在第二部影片中,我們更廣泛地探討 Rails 在應用程式中應扮演的架構角色 - 您應該將其視為平台還是元件組件。
Two Stack CMS
我們建立許多內容豐富的網站,經常使用流行的內容管理系統 (CMS)。最近的一個專案涉及一個全球製造商的市場行銷網站,需要複雜的互動式內容,並具備高可用性和流量需求。我們的回應是套用編輯與發布分離模式,並建立兩個不同的軟體堆疊,分別用於內容建立和傳遞。在這個簡報中,您可以看到這個架構的概觀,以及我們對堆疊之間整合問題的回應,提供即時網站的安全預覽,並處理系統的演進和擴充。
DIP 在實務中的應用
依賴反轉原則 (DIP) 自 90 年代初期就已經存在,即使如此,在解決問題的過程中,似乎很容易忘記它。在一些定義之後,我將展示我個人在實際專案中使用過 DIP 的一些應用,這樣您就可以有一些範例來形成自己的結論。
LMAX 架構
LMAX 是新的零售金融交易平台。因此,它必須處理許多低延遲的交易。這個系統建構在 JVM 平台上,並以一個業務邏輯處理器為中心,它可以在單一執行緒上處理每秒 600 萬個訂單。業務邏輯處理器完全在記憶體中執行,使用事件來源。業務邏輯處理器周圍環繞著 Disruptors,這是一個並發元件,實作一個不需要鎖定的佇列網路。在設計過程中,團隊得出結論,使用佇列的高效能並發模型的最新方向與現代 CPU 設計基本上不一致。
開發企業軟體中的模式
針對各種目錄化企業軟體開發模式的努力進行個人調查。
Ruby Rogues 討論 P of EAA 的集數
Ruby Rogues 是個熱門的 podcast,由固定班底討論 Ruby 程式設計社群中的主題。他們有個固定的讀書會,最近選了 P of EAA 作為他們的特色書籍。因此,他們邀請我擔任節目來賓,討論這本書和它描述的模式,特別是這些模式和 Rails 架構之間的有趣關係。
控制反轉容器和依賴性注入模式
在 Java 社群中,出現了一波輕量級容器,有助於將不同專案的元件組裝成一個有凝聚力的應用程式。這些容器背後有一個共同的模式,說明它們如何執行配線,他們在一個非常通用的名稱「控制反轉」下提到這個概念。在本文中,我深入探討這個模式如何運作,使用更具體的名稱「依賴性注入」,並將它與服務定位器替代方案進行對比。在它們之間做出選擇,不如分離組態和使用的原則重要。
依賴性組合
基於對傳統基於框架的依賴性注入的挫折,我採用了一種組合策略,利用部分應用程式將內容注入模組。當與測試驅動開發結合作為設計流程,並專注於函式而非類別時,模組可以保持清晰、乾淨,而且大多數沒有意外的耦合。
錯誤的架構
軟體開發雜誌將我著作《企業應用程式架構模式》的第 7 章(分佈策略)改編為雜誌中的文章。我猜測他們喜歡它的語氣和包含了分佈式物件設計的第一定律。
專注於事件
一種模式敘述,探討如何使用事件作為系統運作和與同儕協作的焦點。它總結了如何表示事件、如何使用事件在系統之間進行整合,以及在系統架構中使用事件溯源。
GUI 架構
GUI 架構演變的歷史概觀,特別關注模型-檢視-控制器多年來在不同群體中的看法。從歷史角度將其與我的簡報模式聯繫起來。
組織簡報邏輯
使用者介面的模式敘述概觀。討論如何以及為何將網域邏輯與簡報分開,以及如何分隔和同步化資料層。
建構演化架構的前言
最近,我的同事:Neal Ford、Rebecca Parsons 和 Pat Kua 合著了一本名為「建構演化架構」的書。我很榮幸他們請我撰寫前言。
估量康威定律的力量
康威定律(由梅爾文·康威於 1968 年提出)指出,系統的設計受到其設計人員的溝通模式的限制。Birgitta、Mike、James 和我討論了此原則的意義,以及我們在職業生涯中如何看到它的發揮。我們談到了它對微服務概念的影響、與業務能力保持一致的重要性,以及逆向康威策略的作用。
貧血領域模型
這是一種已經存在很長一段時間的反模式,但似乎在目前特別流行。我曾與 Eric Evans 討論過這個問題,我們都注意到它們似乎越來越受歡迎。作為適當 領域模型 的強力推廣者,這不是一件好事。
應用程式邊界
軟體開發中一個未決的問題是決定軟體部分的邊界是什麼。(瀏覽器是否為作業系統的一部分?)許多服務導向架構的倡導者認為應用程式即將消失 - 因此未來的企業軟體開發將是關於將服務組合在一起。
我不認為應用程式會消失,原因與應用程式邊界如此難以繪製的原因相同。基本上,應用程式是社會建構
CQRS
CQRS 代表命令查詢責任隔離。這是一個我第一次聽 Greg Young 描述的模式。其核心概念是您可以使用與用於讀取資訊的模型不同的模型來更新資訊。在某些情況下,這種分離可能很有價值,但請注意,對於大多數系統而言,CQRS 會增加風險複雜性。
斷路器
軟體系統通常會對在不同程序中執行的軟體進行遠端呼叫,這些軟體可能在網路上的不同機器上執行。記憶體內呼叫和遠端呼叫之間的一個重大差異在於,遠端呼叫可能會失敗,或在達到某個逾時限制之前掛起而沒有回應。更糟糕的是,如果您在一個沒有回應的供應商上有很多呼叫者,那麼您可能會用盡關鍵資源,導致多個系統發生連鎖故障。在 Michael Nygard 的優秀著作 Release It 中,他推廣了斷路器模式以防止這種災難性的連鎖反應。
斷路器的基本概念非常簡單。你將受保護的函數呼叫包裝在斷路器物件中,它會監控錯誤。一旦錯誤達到某個閾值,斷路器就會跳閘,所有進一步對斷路器的呼叫都會回傳錯誤,而不會執行受保護的呼叫。通常,如果你斷路器跳閘,你還會想要某種監控警示。
雲端運算
在過去幾年中,「雲端」已成為一個非常炒作過度的術語。炒作過度字詞的一個特徵是它們幾乎沒有定義(是的 NosqlDefinition 我在看著你)。
情境驗證
在我寫作的努力中,我早就打算寫一段關於驗證的內容。這是一個導致很多混淆的領域,對於一些運作良好的技術有一些明確的描述會很好。然而,生活中有太多事情可以寫,遠遠超過時間允許的範圍。
康威定律
在我所支持的軟體架構從業人員中,幾乎所有人都對該領域的任何一般法則都深表懷疑。良好的軟體架構非常特定於情境,分析在各種環境中以不同方式解決的權衡。但如果有一件事他們都同意,那就是康威定律的重要性與力量。它足夠重要,可以影響我遇到的每個系統,而且它足夠強大,如果你試圖對抗它,你註定會失敗。
領域驅動設計
領域驅動設計是一種軟體開發方法,其開發重點在於編寫一個領域模型,對領域的流程和規則有深入的了解。此名稱來自 Eric Evans 於 2003 年出版的一本書,透過型錄模式來描述此方法。從那時起,實務社群進一步發展這些想法,衍生出各種其他書籍和訓練課程。此方法特別適合於複雜的領域,其中需要組織大量通常很混亂的邏輯。
熱切讀取衍生
我在 QCon 舊金山 參加的其中一場有趣的演講,是由 Greg Young 所做的,關於他在最近的系統中使用的一種特定架構。Greg 是 領域驅動設計 的忠實愛好者,在這個案例中,它需要用於必須處理高交易率並向大量使用者提供資料的系統。我發現他的設計有許多有趣的地方,特別是他使用 事件溯源 的方式,但對於這篇文章,我只想探討一個面向,也就是我所稱的熱切讀取衍生。
編輯與發布分離
在過去一年左右的時間裡,我在與 Thoughtworks 專案團隊的對話中,一個經常出現的主題是內容管理系統 (CMS) 的影響力日益增長。它們通常不被視為有幫助的,事實上,有一個明確的跡象表明它們正成為一種令人擔憂的侵入性工具,其用途超過了它們的核心目的,以致於阻礙了整體開發。
在其他令人惱怒的事情中,一個常見的缺點是它們保留每篇文章的一個副本。這個單一副本在建立內容時會進行編輯,並發布給讀者(通常會在某種狀態變更標記上)。
企業應用程式
在本世紀初,我寫了我的書 企業應用程式架構模式。在寫這本書時,我遇到的問題之一是如何為它命名,或者更確切地說,如何稱呼我正在撰寫的軟體系統類型。我一直意識到,我在軟體開發方面的經驗一直專注於一種特定的軟體形式,例如醫療保健記錄、外匯交易、薪資和租賃會計。這些與印表機、遊戲、飛航控制軟體或電話交換機中的嵌入式軟體非常不同。我需要一個名稱來描述這些類型的系統,並決定採用「企業應用程式」這個術語。
企業架構
最近我在 Amazon 上看到幾則對 P of EAA 的負面評價,原因是書中沒有提到企業架構。當然,這是有原因的,因為這本書探討的是企業應用程式架構,也就是如何設計企業應用程式。企業架構是一個不同的主題,探討的是如何將企業中的多個應用程式組織成一個有條理的整體。
事件海報
這是某種我曾遇過幾次的應用程式類型。這種應用程式主要是一種報表應用程式,提供使用者關於某事狀態的即時資訊。這是一個主動式應用程式,使用者可以廣泛地控制他們正在查看的內容類型,他們能夠深入探討特定領域並普遍地操作他們的顯示畫面;然而,它仍然至少主要是一個唯讀應用程式。
說明架構
我們對軟體系統的理解成長過程中遇到的問題之一,就是我們沒有看到足夠的範例。在許多專業領域中,人們透過檢視已完成的事項來學習。範例可以作為靈感、好點子的來源,以及困難的警示。很長一段時間以來,透過這種方式學習軟體變得更加困難。
固定長度字串
檢視大多數在應用程式語言和關聯式資料庫之間進行通訊的程式庫,你會注意到它們將資料庫中的字串類型(char 或 varchar)對應到程式語言中的字串類型。簡單、顯而易見,但這也許是錯的。
內部可重新編程
我在編程時,想要在目前輸入的位置上方新增一行空白行。我使用的編輯器沒有內建這個功能,我終於受不了了,真的很想要這個功能。我快速搜尋了一下 Google,找到幾行程式碼,貼到我的啟動檔案中,執行它們,然後我就用一個按鍵就能在上方建立空白行了。只花了幾分鐘,我不用安裝任何外掛程式,也不用重新啟動編輯器,這對 emacs 使用者來說是日常業務。
控制反轉
控制反轉是擴充架構時常見的現象。事實上,它通常被視為架構的定義特徵。
關鍵介面
軟體開發團隊如果能盡可能頻繁地整合工作,生活會容易許多。他們也發現頻繁地發佈到生產環境很有價值。但是團隊不想讓半成品功能曝光在使用者面前。處理這種緊張情勢的一個有用技巧是建立所有後端程式碼,並進行整合,但不要建立使用者介面。這個功能可以整合和測試,但使用者介面會保留到最後,就像拱心石一樣,加入後完成這個功能,並向使用者揭曉。
分層原則
過去幾天,我一直在挪威參加 Jimmy Nilsson 主辦的企業軟體工作坊。在工作坊中,我們有一個環節,提出並投票選出一些設計原則。
Local D T O
如果你有在關注我的 ThoughtBloggers 同事,你會知道,看起來 我的其中一個機器人熔斷了,澳洲的陽光顯然會燒壞這些瑞典模型。
Jon 對 資料傳輸物件感到厭煩,但並非資料傳輸物件很糟糕,就像任何模式一樣,它們在特定情境下是有用的。模式總是包含兩個部分:如何和何時。你必須知道如何實作它們,也必須知道何時使用它們,以及何時放著不管。
鎖定成本
在我最近的客戶參與中,我預見無伺服器架構非常合適。然而,採用無伺服器架構的想法並未受到我們客戶的歡迎,因為他們擔心供應商鎖定。對於零售商而言,這是一個有趣的時機,因為留在 AWS 中可能意味著 Amazon 作為另一家零售企業將獲得競爭優勢。由於不想支持競爭對手,我的客戶有興趣確保我們選擇的解決方案可以完全移植到其他雲端供應商。
記憶體映像
當人們啟動企業應用程式時,最早出現的問題之一是「我們如何與資料庫溝通」。現在他們可能會問一個稍微不同的問題「我們應該使用哪一種資料庫 - 關係式資料庫或其中一個 NOSQL 資料庫?」。但還有另一個問題需要考慮:「我們是否應該使用資料庫?」
討厭 ORM
幾個月前我在倫敦參加 QCon 會議時,似乎每場演講都包含一些關於物件/關係對應 (ORM) 工具的尖酸刻薄評論。我想我應該更仔細地閱讀寄給講者的會議電子郵件,毫無疑問裡面一定有東西告訴我們每 45 分鐘至少要對 ORM 嗤之以鼻一次。但正如你所見,我想對這種對 ORM 的仇恨反擊一下 - 因為我認為其中很多都是不合理的。
多語持久性
2006 年,我的同事 Neal Ford 創造了多語程式設計一詞,以表達應用程式應該使用多種語言編寫的想法,以利用不同的語言適合解決不同問題的事實。複雜的應用程式結合了不同類型的問題,因此為工作選擇正確的語言可能比嘗試將所有方面都塞進單一語言中更有效率。
在過去幾年,對於新語言,特別是函數式語言,出現了爆炸性的興趣,我常常忍不住花時間深入研究 Clojure、Scala、Erlang 或類似的語言。但是我的時間有限,我將優先考慮另一個更重要的轉變,也就是 DatabaseThaw。第一滴已經從客戶和其他聯絡人那裡傳來,前景誘人。我敢肯定地說,如果你開始一個新的策略性企業應用程式,你就不應該再假設你的持久性應該是關聯式的。關聯式選項可能是正確的選項,但你應該認真考慮其他替代方案。
簡報領域資料分層
模組化資訊豐富程式最常見的方法之一,是將其分為三個廣泛的層級:簡報 (UI)、領域邏輯 (又稱商業邏輯) 和資料存取。因此,你常常看到網路應用程式分為知道如何處理 HTTP 要求和呈現 HTML 的網路層級、包含驗證和計算的商業邏輯層級,以及整理如何管理資料庫或遠端服務中持久性資料的資料存取層級。
簡報領域分離
我發現並遵循的最有用的設計原則之一,就是保持程式(使用者介面)的簡報面向與其他功能之間的良好分離。在過去我看到這項工作完成的那些年裡,我看到了許多好處
已發布介面
發佈介面是我所使用的術語(首次出現在重構中),用於指在定義它的程式碼庫外部使用的類別介面。因此,它的意義比 Java 中的 public 更廣泛,甚至比 C# 中的非內部 public 更廣泛。我在 IEEE Software 的專欄中論證發佈與 public 之間的區別實際上比 public 與 private 之間的區別更重要。
報表資料庫
大多數企業應用程式會使用資料庫儲存持續性資料。此資料庫支援應用程式狀態的作業更新,以及用於決策支援和分析的各種報表。然而,作業需求和報表需求通常截然不同,對架構和資料存取模式有不同的需求。發生這種情況時,通常明智的做法是將報表需求分隔到報表資料庫中,該資料庫會複製必要的作業資料,但會以不同的架構表示它。
要求串流對應
在 Thoughtworks 與我的同事們相處一段時間後,你很快就會得到一個印象,那就是唯一好的企業服務匯流排 (ESB) 就是死掉的 ESB。吉姆·韋伯稱它們為錯誤的義大利麵盒。因此,聽到有人試圖將它們從不需要它們的系統中移除的故事並不少見。
資源池
許多程式需要使用建立和維護成本很高的資源。資料庫連線和執行緒就是其中一些範例。資源池提供了一種管理這些資源的良好方式。
犧牲架構
你坐在會議中,思考著你的團隊在過去幾年來一直在編寫的程式碼。你已經決定,現在你能做的最好的事情就是丟棄所有程式碼,並在全新的架構上重新建構。這讓你對那個注定失敗的程式碼、你花在它上面的時間,以及你在那段時間前所做的決定有何感想?
無伺服器
無伺服器架構是基於網路的系統,其中應用程式開發不使用一般的伺服器程序。相反地,它們僅依賴於第三方服務、用戶端邏輯和服務託管的遠端程序呼叫 (FaaS) 的組合。
軟體元件
自從我進入這個專業領域以來,將軟體開發從費力地編寫程式碼轉變為透過簡單組裝元件來建構強大系統的概念一直是我的目標。這個目標有時會瞥見,但從未真正實現 - 儘管許多技術都曾拋出產業重用的誘餌。
靜態替換
當我聽我們的開發團隊討論他們的工作時,一個共同的主題是他們不喜歡靜態中的事物。我們通常會看到使用靜態初始化項式的靜態變數中包含常見的服務或元件。靜態(在多數語言中)的一個大問題是您無法使用多型性來用一個實作替換另一個實作。這對我們來說很麻煩,因為我們是測試的忠實愛好者 - 而要進行良好的測試,能夠用 服務存根 替換服務非常重要。
絞殺無花果應用程式
當辛蒂和我前往澳洲時,我們在昆士蘭海岸的熱帶雨林中度過了一段時間。這個地區的自然奇觀之一是巨大的 絞殺無花果。它們的種子在樹的上方枝幹中,並逐漸向下生長,直到它們在土壤中生根。經過多年,它們長成奇特而美麗的形狀,同時絞殺並殺死它們的寄主樹。
沉沒成本驅動架構
我發現這是一種令人遺憾的常見架構風格。您的公司購買了一些非常昂貴的基礎設施軟體。然後您被告知即使它不適合該專案,也必須在專案中使用它,而且會造成額外的負擔。在為此支付了所有費用後,您不希望它浪費,對吧?
跨媒體應用程式
在過去幾年中,行動應用程式一直是軟體開發中的熱門項目。與許多軟體交付公司一樣,Thoughtworks 收到許多客戶的請求,要求我們為他們建立行動應用程式。然而,在大部分時間裡,當一家公司要求我們(或任何人)建立行動應用程式時,他們都從錯誤的方向開始。我認為,在大部分情況下,即使您希望使用者與行動裝置互動,您也絕不應該考慮建立行動應用程式。相反地,您需要考慮建立一個可以在多個裝置(行動裝置、桌上型電腦、平板電腦或使用者可能使用的任何裝置)上呈現的單一應用程式。
無交易
幾年前,我與在 eBay 工作的幾位朋友交談。了解人們在大量網站上使用的技術總是很有趣,但最有趣的趣聞之一可能是 eBay 幾乎從不使用資料庫交易。
UI 模式讀物
2006 年夏天,我在 UI 模式 上做了大量工作。從那以後,由於我的主要寫作重點已轉移到 DomainSpecificLanguage(儘管不太明顯),因此它們幾乎被擱置。在此頁面上,我將記錄與該工作相關的連結,以供日後參考。
使用者定義欄位
軟體系統中的一項常見功能是允許使用者在資料結構中定義自己的欄位。考慮一個通訊錄 - 有許多您可能想要新增的東西。隨著每天都有新的社群網路出現,使用者可能希望為其聯絡人新增一個 Bunglr ID 的新欄位。